package com.centerm.bluetooth.common.controller;

import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.annotation.NonNull;
import android.support.v4.content.LocalBroadcastManager;

import com.alibaba.fastjson.JSONObject;
import com.centerm.bluetooth.common.Command;
import com.centerm.bluetooth.common.listener.ITradeListener;
import com.centerm.bluetooth.core.controller.BaseController;
import com.centerm.bluetooth.core.controller.constants.Constants;
import com.centerm.bluetooth.core.controller.constants.WaitEnum;
import com.centerm.bluetooth.ibridge.BluetoothIBridgeDevice;
import com.centerm.bluetooth.model.Respond;
import com.centerm.bluetooth.receive.CMDParseReceiver;
import com.centerm.util.HexUtil;
import com.centerm.util.Logger;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * Created by linwenhui on 2017/4/27.
 */

public class TradeController extends BaseController<ITradeListener> {

    protected final static int OPEN_CARD_READER = 0x01;
    private final static int TRADE_DATA = 0x02;
    private int type;
    private ReadResultReceiver readResultReceiver;


    public TradeController(@NonNull Context context) {
        super((byte) 0x03, context);
    }

    public boolean openCardReader(byte[] random, int timeout, int money) throws IOException {
        if (wait == WaitEnum.FREE) {
            ByteArrayOutputStream params = new ByteArrayOutputStream();
            params.write(0x07);
            params.write(random);
            params.write(0x0);
            params.write(timeout);
            params.write(new byte[]{0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20});
            String moneyString;
            if (money >= 0) {
                moneyString = String.format("%012d", money);
            } else {
                moneyString = "FFFFFFFFFFFF";
            }
            params.write(HexUtil.hexStr2Bytes(moneyString));
            params.write(0x0);
            params.write(0x0);
            params.write(0x00);
            params.write(0x01);
            type = OPEN_CARD_READER;
            final boolean result = send(Command.OPEN_CARD_READER, params.toByteArray());
            if (result) {
                registerSwiperCardResult();
                setTimeOut(timeout);
            }
            params.close();
            return result;
        }
        return false;
    }

    public void registerSwiperCardResult() {
        if (readResultReceiver == null)
            readResultReceiver = new ReadResultReceiver();
        LocalBroadcastManager.getInstance(context).registerReceiver(readResultReceiver, new IntentFilter(Constants.CMD_ACTION + "0302"));
    }

    public boolean getTradeData() throws IOException {
        if (wait == WaitEnum.FREE || wait == WaitEnum.WAIT_SWIPER_COMPELETE) {
            type = TRADE_DATA;
            boolean res = send(Command.TRADE_DATA, null);
            if (res)
                setTimeoutTimer();
            return res;
        }
        return false;
    }

    @Override
    public void onDataReceived(BluetoothIBridgeDevice device, Respond respond) {
        super.onDataReceived(device, respond);
        switch (type) {
            case OPEN_CARD_READER:
                wait = WaitEnum.WAIT_SWIPER;
                if (baseListener != null)
                    baseListener.onWaitForSwipeCard();
                break;
            case TRADE_DATA:
                try {
                    parseTradeData(respond.getContent());
                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;
        }
    }

    protected void parseTradeData(byte[] params) throws IOException {
        JSONObject obj = new JSONObject();
        //随机数
        byte[] randombytes = new byte[8];
        System.arraycopy(params, 0, randombytes, 0, 8);
        obj.put("random", HexUtil.byte2HexStr(randombytes));
        Logger.i(randombytes, Logger.TYPE.CODE16);

        //卡PAN
        byte[] panbytes = new byte[10];
        System.arraycopy(params, 8, panbytes, 0, 10);
        obj.put("pan", HexUtil.byte2HexStr(panbytes).replace("F", "").replace("f", ""));
        Logger.i(panbytes, Logger.TYPE.CODE16);

        //有效期
        byte[] expireDateBytes = new byte[2];
        System.arraycopy(params, 18, expireDateBytes, 0, 2);
        obj.put("expireDate", HexUtil.byte2HexStr(expireDateBytes));
        Logger.i(expireDateBytes, Logger.TYPE.CODE16);

        //二磁道数据密文长度
        int tradeTwoLen = params[20] & 0xFF;
        Logger.i(" tradeTwoLen == " + tradeTwoLen);
        if (tradeTwoLen == 0xFF) {
            obj.put("tradeTwo", "");
        } else {
            byte[] tradeTwoBytes = new byte[tradeTwoLen];
            System.arraycopy(params, 21, tradeTwoBytes, 0, tradeTwoLen);
            obj.put("tradeTwo", HexUtil.byte2HexStr(tradeTwoBytes));
        }


        //三磁道数据长度
        int tradeThreeLen = params[21 + tradeTwoLen] & 0xFF;
        Logger.i(" tradeTwoLen == " + tradeThreeLen);
        if (tradeThreeLen == 0xFF) {
            obj.put("tradeThree", "");
        } else {
            byte[] tradeThreeBytes = new byte[tradeThreeLen];
            System.arraycopy(params, 22 + tradeTwoLen, tradeThreeBytes, 0, tradeThreeLen);
            obj.put("tradeThree", HexUtil.byte2HexStr(tradeThreeBytes));
        }

        if (baseListener != null)
            baseListener.onSwiperCompelete(obj.toJSONString());

    }

    private class ReadResultReceiver extends CMDParseReceiver {

        @Override
        public void onReceive(Context context, Intent intent, byte[] params, int paramLen) {
            wait = WaitEnum.FREE;
            if (paramLen == 0) {
                if (baseListener != null) {
                    baseListener.onCardType(0x01);
                }
            } else {
                switch (params[0]) {
                    case 0x00://刷卡成功，加密处理成功
                        wait = WaitEnum.WAIT_SWIPER_COMPELETE;
                        if (baseListener != null)
                            baseListener.onSwiperSuc();
                        break;
                    case 0x01://刷卡成功，加密处理失败
                        if (baseListener != null)
                            baseListener.onSwiperFalse();
                        break;
                    case 0x03://刷卡超时
                        if (baseListener != null)
                            baseListener.onSwiperTimeout();
                        break;
                    case 0x04: //取消刷卡
                        if (baseListener != null)
                            baseListener.onCancelSwipeCard();
                        break;
                    case 0x05: //IC卡已插入
                        wait = WaitEnum.WAIT_SWIPER_COMPELETE;
                        if (baseListener != null)
                            baseListener.onICInsert();
                        break;
                    case 0x07: //非接挥卡
                        wait = WaitEnum.WAIT_SWIPER_COMPELETE;
                        if (baseListener != null)
                            baseListener.onNFInsert();
                        break;
                    default:
                        if (baseListener != null)
                            baseListener.onCardType(params[0]);
                }

            }

        }
    }

}
